package com.ajhlp.spring_modules.db.multiSource;

import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import com.ajhlp.spring_modules.db.dao.IDBSourceMetaDao;
import com.ajhlp.spring_modules.db.multiSource.metaModel.DBSource_BasicInfo;
import com.ajhlp.spring_modules.db.multiSource.metaModel.DBSource_DataField;
import com.ajhlp.spring_modules.db.multiSource.metaModel.DBSource_DataSet;
import com.ajhlp.spring_modules.db.multiSource.metaModel.DBSource_Query;
import com.ajhlp.spring_modules.db.multiSource.metaModel.DBSource_Type;
/**
 * 数据源描述服务的数据库实现类
 * @author ajhlp
 *
 */
@Service
public class DBServerDBSourceMetaServiceImpl implements IDBSourceMetaService {

	private Logger log = Logger.getLogger(getClass());
	//数据库操作类
	@Resource
	private IDBSourceMetaDao sourceMetaDao;
	
	/**
	 * 获得保存数据源描述数据的操作类
	 * @return
	 */
	public IDBSourceMetaDao getSourceMetaDao() {
		return sourceMetaDao;
	}
	/**
	 * 设置保存数据源描述数据的操作类
	 * @param sourceMetaDao
	 */
	public void setSourceMetaDao(IDBSourceMetaDao sourceMetaDao) {
		this.sourceMetaDao = sourceMetaDao;
	}

	public void saveBasicInfo(DBSource_BasicInfo basicInfo)
			throws DBSourceMetaSaveFailureException {
		// TODO Auto-generated method stub
		try {
			Assert.notNull(basicInfo,"数据源基本信息不能为空");
			Assert.notNull(basicInfo.getName(),"数据源基本信息名称不能为空");
			Assert.state(basicInfo.getDbSourceTypeId() <= 0, "数据源类型不正确");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			throw new DBSourceMetaSaveFailureException(basicInfo, e.getMessage());
		}
		
		//设置jdbc驱动
		basicInfo.setDriverClass(this.getDriverClass(basicInfo));
		//设置连接字符串
		basicInfo.setUrl(this.getJdbcUrl(basicInfo));
		//设置创建时间、最后修改时间
		if(basicInfo.getId() == 0){
			basicInfo.setCreateDate(new Date());
			basicInfo.setLastEditDate(basicInfo.getCreateDate());
		}else{
			basicInfo.setLastEditDate(new Date());
		}
		
		try {
			//新建
			if(basicInfo.getId() == 0){
				this.sourceMetaDao.saveBasicInfo(basicInfo);
			//更新
			}else{
				this.sourceMetaDao.updateBasicInfo(basicInfo);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			log.error("保存数据源基本信息失败", e);
			throw new DBSourceMetaSaveFailureException(basicInfo, e.getMessage());
		}
		
	}

	public void saveDataSetInfo(DBSource_DataSet dataSet)
			throws DBSourceMetaSaveFailureException {
		// TODO Auto-generated method stub
		try {
			Assert.notNull(dataSet,"数据集信息不能为空");
			Assert.notNull(dataSet.getName(),"数据集信息名称不能为空");
			Assert.state(dataSet.getDbSourceBasicInfoId() <= 0, "所属数据源不正确");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			throw new DBSourceMetaSaveFailureException(dataSet, e.getMessage());
		}
		//设置创建时间、最后修改时间
		if(dataSet.getId() == 0){
			dataSet.setCreateDate(new Date());
			dataSet.setLastEditDate(dataSet.getCreateDate());
		}else{
			dataSet.setLastEditDate(new Date());
		}
		try {
			//新建
			if(dataSet.getId() == 0){
				this.sourceMetaDao.saveDataSetInfo(dataSet);
			//更新
			}else{
				this.sourceMetaDao.updateDataSetInfo(dataSet);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			log.error("保存数据集信息失败", e);
			throw new DBSourceMetaSaveFailureException(dataSet, e.getMessage());
		}
	}

	public void saveDataFieldInfo(DBSource_DataField dataField)
			throws DBSourceMetaSaveFailureException {
		// TODO Auto-generated method stub
		try {
			Assert.notNull(dataField,"数据字段信息不能为空");
			Assert.notNull(dataField.getName(),"数据字段信息名称不能为空");
			Assert.notNull(dataField.getType(),"数据字段类型不能为空");
			Assert.notNull(dataField.getQueryCondition(),"数据字段是否为查询条件不能为空");
			Assert.state(dataField.getDbSourceDataSetId() <= 0, "所属数据集不正确");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			throw new DBSourceMetaSaveFailureException(dataField, e.getMessage());
		}
		//设置创建时间、最后修改时间
		if(dataField.getId() == 0){
			dataField.setCreateDate(new Date());
			dataField.setLastEditDate(dataField.getCreateDate());
		}else{
			dataField.setLastEditDate(new Date());
		}
		try {
			//新建
			if(dataField.getId() == 0){
				this.sourceMetaDao.saveDataFieldInfo(dataField);
			//更新
			}else{
				this.sourceMetaDao.updateDataFieldInfo(dataField);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			log.error("保存数据集信息失败", e);
			throw new DBSourceMetaSaveFailureException(dataField, e.getMessage());
		}
	}

	public void saveDataFieldInfo(List<DBSource_DataField> fields)
			throws DBSourceMetaSaveFailureException {
		// TODO Auto-generated method stub
		try {
			Assert.notNull(fields,"数据字段信息不能为空");
			Assert.notEmpty(fields,"数据字段信息集合不能为空");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			throw new DBSourceMetaSaveFailureException(fields, e.getMessage());
		}
		
		for(DBSource_DataField field : fields){
			this.saveDataFieldInfo(field);
		}
	}

	public List<DBSource_BasicInfo> queryBasicInfo(DBSource_Query conditon)
			throws DBSourceMetaQueryFailureException {
		// TODO Auto-generated method stub
		return this.sourceMetaDao.queryBasicInfo(conditon);
	}

	public List<DBSource_DataSet> queryDataSet(DBSource_Query conditon)
			throws DBSourceMetaQueryFailureException {
		// TODO Auto-generated method stub
		return this.sourceMetaDao.queryDataSetInfo(conditon);
	}

	public List<DBSource_DataField> queryDataField(DBSource_Query conditon)
			throws DBSourceMetaQueryFailureException {
		// TODO Auto-generated method stub
		return this.sourceMetaDao.queryDataFieldInfo(conditon);
	}

	public List<DBSource_Type> queryDBSourceType(DBSource_Query condition)
			throws DBSourceMetaQueryFailureException {
		// TODO Auto-generated method stub
		return this.sourceMetaDao.queryAllTypes(condition);
	}
	
	/**
	 * 获取jdbc驱动
	 * @param basicInfo 数据源基本信息
	 * @return
	 */
	public String getDriverClass(DBSource_BasicInfo basicInfo) {
		
		DBSource_Type type = null;
		
		try {
			DBSource_Query query = new DBSource_Query();
			query.setId(basicInfo.getDbSourceTypeId());
			type = this.queryDBSourceType(query).get(0);
		} catch (DBSourceMetaQueryFailureException e) {
			// TODO Auto-generated catch block
			log.error("查询数据源类型失败", e);
		}
			
		if(type == null){
			return "";
		}else{
			return type.getDriverClass();
		}
	}
	/**
	 * 生成jdbc链接URL
	 * @param basicInfo
	 * @return
	 */
	public String getJdbcUrl(DBSource_BasicInfo basicInfo){
		DBSource_Type type = null;
		
		try {
			DBSource_Query query = new DBSource_Query();
			query.setId(basicInfo.getDbSourceTypeId());
			type = this.queryDBSourceType(query).get(0);
		} catch (DBSourceMetaQueryFailureException e) {
			// TODO Auto-generated catch block
			log.error("查询数据源类型失败", e);
		}
			
		if(type == null){
			return "";
		}else{
			return type.getJdbcUrl().replaceAll("\\{ip\\}", basicInfo.getIp())
					.replaceAll("\\{port\\}", basicInfo.getPort())
					.replaceAll("\\{schema\\}", basicInfo.getDbSchema());
		}
	}

}
